package com.huilian.iotbox.mqtt.server.base.handler.penetrate.vendmach;

import com.huilian.iotbox.aliyun.service.PubService;
import com.huilian.iotbox.data.cmd.PositiveDataFrameCMD;
import com.huilian.iotbox.data.cmd.VendmachResponseDataFrameCMD;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.dto.DisplayRackItemDto;
import com.huilian.iotbox.data.utils.IotBoxUtil;
import com.huilian.iotbox.data.vo.DeviceVo;
import com.huilian.iotbox.mqtt.server.base.handler.penetrate.PenetrateHandlerStrategy;
import com.huilian.iotbox.mqtt.server.base.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * @author 谢洛涛
 * @date 2023/10/5 21:14
 */
@Slf4j
@Service("penetrateHandlerServiceC90E")
public class ShipmentC90EHandler implements PenetrateHandlerStrategy {

    @Value("${huilian.iot.productKey}")
    private String productKey;
    @Autowired
    private PubService pubService;
    @Autowired
    DeviceService deviceService;
    @Autowired
    private OrderService orderService;
    @Resource
    private RabbitSenderService rabbitSenderService;
    @Resource
    private DisplayRackItemService displayRackItemService;

    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;
    @Override
    public void process(String content, String deviceNo, Integer positionId) throws Exception {
        log.info("进入 售货机是否收到订阅消息");

        DeviceVo deviceVo = deviceService.findOneDeviceByDeviceNo(deviceNo);
        // 支付唯一码
        final String payNoHex = content.substring(28, 42);
        log.info("payNoHex：" + payNoHex);
        final String payNo = IotBoxUtil.convertHexToString(payNoHex).trim();
        log.info("payNo：" + payNo);
        final String controlBoardCmd = content.substring(26, 28);
        log.info("controlBoardCmd：" + controlBoardCmd);
        if(controlBoardCmd.equals("05")){
            log.info(deviceNo + "获取点击测试消息: {}", content);
            // 电机测试
            final Integer line = IotBoxUtil.singleHex2Int(content.substring(40, 42));
            final Integer rank = IotBoxUtil.singleHex2Int(content.substring(42, 44));
            final Integer state = IotBoxUtil.singleHex2Int(content.substring(44, 46));
            String penetrateTcp = PositiveDataFrameCMD.penetrate(VendmachResponseDataFrameCMD.shipmentReport(deviceNo,payNo,"05","0E"));
            pubService.pub(penetrateTcp, deviceNo, productKey);

            //获取到检测结果直接修改
            DisplayRackItemDto updateDisplayRackItemDto = new DisplayRackItemDto();
            updateDisplayRackItemDto.setDeviceId(deviceVo.getId());
            updateDisplayRackItemDto.setHierarchy(line);
            updateDisplayRackItemDto.setFreightLane(rank);
            updateDisplayRackItemDto.setStatus(state.equals(1));
            displayRackItemService.updateStatus(updateDisplayRackItemDto);

            String detectionKey = String.format(RedisKey.MOTOR_TEST_REFRESH_TIME, deviceVo.getId());
            Integer testingNumber = (Integer) redisCacheTemplate.opsForValue().get(detectionKey);
            if (!StringUtils.isEmpty(testingNumber)){
                testingNumber--;
                if (testingNumber != 0){
                    redisCacheTemplate.opsForValue().set(detectionKey, testingNumber, testingNumber * 5L, TimeUnit.SECONDS);
                }else{
                    redisCacheTemplate.delete(detectionKey);
                }
            }
            //查询故障数
            DisplayRackItemDto selectDisplayRackItemDto = new DisplayRackItemDto();
            selectDisplayRackItemDto.setDeviceId(deviceVo.getId());
            selectDisplayRackItemDto.setStatus(true);
            selectDisplayRackItemDto.setHierarchy(line);
            int numberOfFailures = displayRackItemService.numberOfFailures(selectDisplayRackItemDto);
            //电机状态 1正常,2故障,3检测中
            if (state.equals(0)){
                deviceVo.setMotorStatus(1);
            }else if (state.equals(1)){
                deviceVo.setMotorStatus(2);
            }else {
                deviceVo.setMotorStatus(3);
            }
            deviceVo.setHierarchy(line);
            deviceVo.setFreightLane(rank);
            deviceVo.setNumberOfFailures(numberOfFailures);
            rabbitSenderService.disposeMotorTestingResult(deviceVo);


        } else if(controlBoardCmd.equals("06") || controlBoardCmd.equals("FF")){
            if(controlBoardCmd.equals("FF")){
                log.info("重复订单成功回复: {}", content);
            }
            log.info(deviceNo + "获取售货机出货消息: {}", content);
            // 处理出货
            String key = String.format(RedisKey.VENDING_MACHINE_PROCESSING_STATUS,deviceNo, payNo);
            Integer state =  (Integer) redisCacheTemplate.opsForValue().get(key);
            if(state == null) {
                // 正常2秒内能处理好，但防止真的有20个商品的订单，所以加成10秒
                redisCacheTemplate.opsForValue().set(key,1,10,TimeUnit.SECONDS);
                Boolean bool = orderService.processingShipments(content, deviceVo, payNo, productKey);
                if (bool) {
                    String penetrateTcp = PositiveDataFrameCMD.penetrate(VendmachResponseDataFrameCMD.shipmentReport(deviceNo, payNo, "06","0E"));
                    pubService.pub(penetrateTcp, deviceNo, productKey);
                    log.info("回复服务器");
                    redisCacheTemplate.delete(key);
                }
            }else{
                log.info("当前订单状态正在处理中:{}",payNo);
            }
        }
    }


//    private void common(DeviceVo deviceVo, int state) {
//        String k = String.format(RedisKey.MQTT_MESSAGE_NUMBER2, deviceVo.getId(), IotBoxCmdEnum.AAF101DD.getCmdId());
//        Set<String> keys = redisHelper.keys(k + "*");
//        log.info("k：" + k);
//        log.info("keys：" + keys.toString());
//        for (String key : keys) {
//            log.info("key：" + key);
//            redisCacheTemplate.opsForValue().set(key, state, 10, TimeUnit.SECONDS);
//        }
//    }
}
